///////////////////////////////////////////////////////////////////////////
//
// Spring Engine Source File.
// Copyright (C), Dengtao 2011-2021
// ----------------------------------------------------------------------
// File name:   SfMemoryAllocManager.cpp
// Version:     v1.0.0
// Created:     2013/06/13 23:33 by dengtao
// Compilers:   Visual Studio 2008
// Description: 
// ----------------------------------------------------------------------
// History:
//
///////////////////////////////////////////////////////////////////////////

#include "SfMemoryAllocManager.h"
#include "SfMemoryAllocator.h"

namespace Sunflower
{

//
//Summary:
//	Default constructor.
MemoryAllocManager::MemoryAllocManager()
	: m_Allocator(SfNull)
	, m_Tracker(SfNull)
{
}

//
//Summary:
//	virtual destructor.
MemoryAllocManager::~MemoryAllocManager()
{
	SfSafeDelete(m_Allocator);
}

//
//Summary:
//	Allocate a block from MemoryAllocManager.
void* MemoryAllocManager::Alloc(size_t size)
{
	if (size == 0)
	{
		size = 1;
	}

	void* p = MemAlloc(size);

	if (SfIsNullPtr(p))
	{
		// if alloc failed, purge caches and then re-alloc
		// event : MemoryWarning
		OnMemoryWarning(size);
		RaiseMemoryWarning(size);

		p = MemAlloc(size);
	}

	return p;
}

void* MemoryAllocManager::Alloc(size_t size, const char* file, int line, const char* func)
{
	void* p = this->Alloc(size);

	if (SfIsValidPtr(p) && SfIsValidPtr(m_Tracker))
	{
		m_Tracker->ProcMemoryAlloc(p, size, file, line, func);
	}

	return p;
}

//
//Summary:
//	Free a object from MemoryAllocManager.
bool MemoryAllocManager::Free(void* p)
{
	if (p)
	{
		bool ret = MemFree(p);

		if (ret && SfIsValidPtr(m_Tracker))
		{
			m_Tracker->ProcMemoryFree(p);
		}

		return ret;
	}

	return false;
}

bool MemoryAllocManager::Free(void* p, const char* file, int line, const char* func)
{
	SfUnreferencedParam(file);
	SfUnreferencedParam(line);
	SfUnreferencedParam(func);

	SfAssert(false);
	
	return this->Free(p);
}

//
//Summary:
//	callback when alloc failed once.
void MemoryAllocManager::OnMemoryWarning(size_t requestSize)
{
	SfUnreferencedParam(requestSize);
}

}